package cn.stylefeng.guns.modular.shuheng.controller;


import cn.stylefeng.guns.config.properties.GunsProperties;
import cn.stylefeng.guns.core.common.constant.Constants;
import cn.stylefeng.guns.core.common.exception.BizExceptionEnum;
import cn.stylefeng.guns.core.common.page.LayuiPageFactory;
import cn.stylefeng.guns.core.log.LogObjectHolder;
import cn.stylefeng.guns.core.shiro.ShiroKit;
import cn.stylefeng.guns.core.shiro.ShiroUser;
import cn.stylefeng.guns.core.util.DateUtil;
import cn.stylefeng.guns.core.util.DownloadFileUtil;
import cn.stylefeng.guns.core.util.FileUtil;
import cn.stylefeng.guns.core.util.ObjectExcelRead;
import cn.stylefeng.guns.modular.shuheng.entity.Content;
import cn.stylefeng.guns.modular.shuheng.entity.Data;
import cn.stylefeng.guns.modular.shuheng.entity.Level;
import cn.stylefeng.guns.modular.shuheng.service.ContentService;
import cn.stylefeng.guns.modular.shuheng.service.DataService;
import cn.stylefeng.guns.modular.shuheng.service.LevelService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.RequestEmptyException;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.models.auth.In;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.*;
import java.net.URLEncoder;
import java.util.*;

import org.springframework.stereotype.Controller;
import cn.stylefeng.roses.core.base.controller.BaseController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zhengpp
 * @since 2021-03-07
 */
@Controller
@RequestMapping("/level")
public class JobController extends BaseController {

   private String PREFIX = "/modular/shuheng/job/";

   @Autowired
   private LevelService  levelService;

   @Autowired
   private ContentService contentService;

   @Autowired
   private DataService dataService;

   @Autowired
   private GunsProperties gunsProperties;

   @RequestMapping("")
   public String index(Model model){
      Calendar calendar = Calendar.getInstance();
      Integer year = calendar.get(Calendar.YEAR);
      List<Integer> list = new ArrayList<>();
      list.add(year);
      list.add(year +1);
      list.add(year +2);
      model.addAttribute("list",list);
      return PREFIX + "level.html";
   }

   @RequestMapping("/list")
   @ResponseBody
   public Object list(@RequestParam(value = "levelName", required = false) String levelName,
                      @RequestParam(value = "year", required = false) String year){
      if(ToolUtil.isEmpty(year)){
         Calendar calendar = Calendar.getInstance();
         year = calendar.get(Calendar.YEAR)+"";
      }
      Page<Map<String,Object>> page = levelService.listLevel(levelName,year);
      return LayuiPageFactory.createPageInfo(page);
   }

   @RequestMapping("/level_add")
   public String addView() {
      return PREFIX + "level_add.html";
   }

   @RequestMapping(value = "/add")
   @ResponseBody
   public ResponseData add(Level level) {
      if (level == null) {
         throw new RequestEmptyException();
      }
      this.levelService.save(level);
      return SUCCESS_TIP;
   }


   @RequestMapping("/level_edit")
   public String editView(@RequestParam Long levelId){
      if (ToolUtil.isEmpty(levelId)) {
         throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
      }
      //用来记录日志
      Level level = this.levelService.getById(levelId);
      LogObjectHolder.me().set(level);
      return PREFIX + "level_edit.html";
   }

   @RequestMapping(value = "/edit")
   @ResponseBody
   public ResponseData edit(Level level){
      if (level == null) {
         throw new RequestEmptyException();
      }
      this.levelService.updateById(level);
      return SUCCESS_TIP;
   }

   @RequestMapping(value = "/getLevelInfo")
   @ResponseBody
   public ResponseData getLevelInfo(@RequestParam Long levelId) {
      if (ToolUtil.isEmpty(levelId)) {
         throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
      }
      Level level = this.levelService.getById(levelId);
      return ResponseData.success(level);
   }


   /**
   * 删除
   * @param levelId
   * @return
   */
   @RequestMapping(value = "/delete")
   @ResponseBody
   public ResponseData delete(@RequestParam Long levelId) {
      if (ToolUtil.isEmpty(levelId)) {
         throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
      }
      QueryWrapper<Content> contentQueryWrapper = new QueryWrapper<>();
      contentQueryWrapper.eq("level_id",levelId);
      List<Content> contentList = contentService.list(contentQueryWrapper);
      if(contentList!=null && contentList.size()>0){
         for(Content content:contentList){
            QueryWrapper<Data> dataQueryWrapper = new QueryWrapper<>();
            dataQueryWrapper.eq("content_id",content.getContentId());
            dataService.remove(dataQueryWrapper);
         }
      }
      contentService.remove(contentQueryWrapper);
      this.levelService.removeById(levelId);
      return SUCCESS_TIP;
   }

   /**
    * 跳转按年度复制页面
    * @return
    */
   @RequestMapping("toCopy")
   public String toCopy(Model model){
      Calendar calendar = Calendar.getInstance();
      Integer year = calendar.get(Calendar.YEAR);
      List<Integer> list = new ArrayList<>();
      list.add(year-1);
      list.add(year);
      list.add(year +1);
      list.add(year +2);
      model.addAttribute("list",list);
      return PREFIX + "copy.html";
   }

   @RequestMapping("/copy")
   @ResponseBody
   public ResponseData copy(@RequestParam(value = "year",required = false)Integer year,
                            @RequestParam(value = "targetYear",required = false)Integer targetYear){
      if(ToolUtil.isOneEmpty(year,targetYear)){
         throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
      }
      QueryWrapper<Level> wrapper = new QueryWrapper<>();
      wrapper.eq("year",year);
      List<Level> levelList = levelService.list(wrapper);
      if(levelList==null || levelList.size()==0){
         throw new ServiceException(BizExceptionEnum.LEVEL_NOT_EXIT_COPY);
      }
      //查询目标年份是否已经有数据，有责提示需要先删除目标年份数据
      QueryWrapper<Level> tarWrapper = new QueryWrapper<>();
      tarWrapper.eq("year",targetYear);
      List<Level> targetList = levelService.list(tarWrapper);
      if(targetList!=null && targetList.size()>0){
         throw new ServiceException(BizExceptionEnum.TARGET_LEVEL_EXIT);
      }
      for(int i=0;i<levelList.size();i++){
         Level level = levelList.get(i);
         QueryWrapper<Content> contentWrapper = new QueryWrapper<>();
         contentWrapper.eq("level_id",level.getLevelId());
         List<Content> contentList = contentService.list(contentWrapper);
         //添加level
         level.setYear(targetYear);
         level.setLevelId(null);
         levelService.save(level);//保存后返回levelId

         //level节点下的data
         QueryWrapper<Data> dWrapper = new QueryWrapper<>();
         dWrapper.eq("level_id",level.getLevelId());
         List<Data> dList = dataService.list(dWrapper);
         if(dList!=null && dList.size()>0){
            for(int k=0;k<dList.size();k++){
               dList.get(k).setDataYear(targetYear);
               dList.get(k).setDataId(null);
               dList.get(k).setLevelId(level.getLevelId());
            }
            dataService.saveBatch(dList);
         }

         if(contentList!=null && contentList.size()>0){
            for(int j=0;j<contentList.size();j++){
               Content content = contentList.get(j);
               QueryWrapper<Data> dataWrapper = new QueryWrapper<>();
               dataWrapper.eq("content_id",content.getContentId());
               List<Data> dataList = dataService.list(dataWrapper);

               //设置content
               content.setYear(targetYear);
               content.setContentId(null);
               content.setLevelId(level.getLevelId());
               contentService.save(content);//返回contentId
               if(dataList!=null && dataList.size()>0){
                  for(int a=0;a<dataList.size();a++){
                     dataList.get(a).setDataYear(targetYear);
                     dataList.get(a).setDataId(null);
                     dataList.get(a).setContentId(content.getContentId());
                  }
                  dataService.saveBatch(dataList);
               }
            }
         }
      }

      return SUCCESS_TIP;
   }

   /**
    * 导出
    * @param year
    * @return
    */
   @RequestMapping("/export")
   public void export(@RequestParam Integer year,
                              HttpServletRequest request, HttpServletResponse response){
      if(ToolUtil.isEmpty(year)){
         throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
      }

      try {
         OutputStream out = response.getOutputStream();
         response.setCharacterEncoding("UTF-8");
         String path = createZip(year,request);
         byte[] data = getStream(path);
         // 压缩包名称
         response.setHeader("Content-Disposition",
                 "attachment;filename=" + URLEncoder.encode(year + "年度任务.zip", "utf-8"));
         response.addHeader("Content-Length", "" + data.length);
         response.setContentType("application/octet-stream;charset=UTF-8");
         IOUtils.write(data, out);
         out.close();
      } catch (IOException e) {
         throw new ServiceException(BizExceptionEnum.SERVER_ERROR);
      }
   }

   private byte[] getStream(String filePath) {
      byte[] buffer = null;
      File file = new File(filePath);
      FileInputStream fis = null;
      ByteArrayOutputStream bos = null;
      try {
         bos = new ByteArrayOutputStream();
         fis = new FileInputStream(file);
         byte[] b = new byte[1024];
         int n;
         while ((n = fis.read(b)) != -1) {
            bos.write(b, 0, n);
         }
         buffer = bos.toByteArray();
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      }catch (IOException e) {
         e.printStackTrace();
      }finally {
         try {
            if(fis!=null)
               fis.close();
            if(bos!=null)
               bos.close();
         }catch (IOException e) {
            e.printStackTrace();
         }
      }
      return buffer;
   }

   private String createZip(Integer year,HttpServletRequest request) throws IOException {
      QueryWrapper<Level> levelWrapper = new QueryWrapper<>();
      levelWrapper.eq("year",year);
      List<Level> levelList = levelService.list(levelWrapper);
      if(levelList==null || levelList.size()==0){
         throw new ServiceException(BizExceptionEnum.LEVEL_NOT_EXIT);
      }
      List<Content> contentList = new ArrayList<>();
      List<Data> dataList = new ArrayList<>();
      for(int i=0;i<levelList.size();i++){
         Level level = levelList.get(i);
         //level节点下的cotnent
         QueryWrapper<Content> contentWrapper = new QueryWrapper<>();
         contentWrapper.eq("level_id",level.getLevelId());
         List<Content> cList = contentService.list(contentWrapper);
         contentList.addAll(cList);
         //level节点下的data
         QueryWrapper<Data> dWrapper = new QueryWrapper<>();
         dWrapper.eq("level_id",level.getLevelId());
         List dList = dataService.list(dWrapper);
         if(dList!=null && dList.size()>0){
            dataList.addAll(dList);
         }

         if(cList!=null && cList.size()>0){
            for(int j=0;j<cList.size();j++){
               QueryWrapper<Data> dataWrapper = new QueryWrapper<>();
               dataWrapper.eq("content_id",cList.get(j).getContentId());
               dataList.addAll(dataService.list(dataWrapper));
            }

         }

      }
      Map<String,Object> map = new HashMap<>();
      map.put("levelList",levelList);
      map.put("contentList",contentList);
      map.put("dataList",dataList);
      String json = JSONObject.toJSONString(map);
      String rootPath = FileUtil.getRootPath(request,gunsProperties.getJarName());
      String filePath = Constants.EXPROT_PATH + year + File.separator ;
      File dir = new File(rootPath+filePath);
      if(!dir.exists()){
         dir.mkdirs();
      }
      File jsonFile = new File(rootPath + filePath + Constants.JOB_JSON);
      if(!jsonFile.exists()){
         jsonFile.createNewFile();
      }
      FileOutputStream outputStream = new FileOutputStream(jsonFile);
      outputStream.write(json.getBytes("UTF-8"));

      String zipPath = rootPath + Constants.EXPROT_PATH + "json.zip";
      FileUtil.compressionFile(rootPath + filePath ,zipPath);

      return zipPath;
   }

   /**
    *跳转导入页面
    * @return
    */
   @RequestMapping("/toExcelImport")
   public String toExcelImport(Model model) {
      Integer year = DateUtil.getNowYear();
      List<Integer> list = new ArrayList<>();
      list.add(year);
      list.add(year +1);
      list.add(year +2);
      model.addAttribute("list",list);
      return PREFIX + "excelImport.html";
   }

   /**浏览器下载excel
    * @param request
    * @param response
    */
   @RequestMapping("/downloadFile")
   @ResponseBody
   public void downloadFile(@RequestParam(value = "excelName",required = false)String excelName,
                            @RequestParam(value = "fileName",required = false)String fileName,
                            HttpServletRequest request, HttpServletResponse response)throws Exception{
      ClassPathResource resource = new ClassPathResource(Constants.DOWNLOAD_EXCEL_PATH+excelName);
      DownloadFileUtil.downloadFile(resource.getInputStream(),fileName,request,response);
   }


   @RequestMapping(value = "/excelimport")
   @ResponseBody
   @Transactional
   public Map<String,Object> saveExcelImport(@RequestParam(value = "excelPath", required = true) String excelPath,
                                             HttpServletResponse response, HttpServletRequest request) throws Exception {
      //返回结果
      Map<String,Object> result = new HashMap<>();
      String realPath = FileUtil.getRootPath(request,gunsProperties.getJarName()) + excelPath;
      @SuppressWarnings({ "unchecked", "rawtypes" })
      List<Map<String,Object>> listPd = (List) ObjectExcelRead.readExcel(realPath, 2, 0, 0);
      //循环添加数据
      if (listPd != null) {

      }
      //删除已上传的excel文件
      File file = new File(realPath);
      file.delete();
      result.put("msg", "success");
      return result;
   }

   @RequestMapping("/jobImg")
   public void jobImg( HttpServletResponse response,HttpServletRequest request){
      try {
         //  本地的pdf文件
         Calendar calendar = Calendar.getInstance();
         int year = calendar.get(Calendar.YEAR);
         String filePath = ResourceUtils.getURL("classpath:application.yml").getPath();
         int result = filePath.lastIndexOf("/"+gunsProperties.getJarName()+"!/");
         if(result > -1) {
            //虚拟路径不能去掉file:
            filePath = filePath.substring(0, result).substring(6) + "/files/"+ year+".pdf";
         }
         showPdf(response,filePath);

      }catch (Exception e) {
         e.printStackTrace();
      }

   }

   /**
    * 预览pdf文件工具类
    * @param response
    * @param fileName
    */
   public static void showPdf( HttpServletResponse response, String fileName) throws IOException{
      response.setContentType("application/pdf");
      FileInputStream in = new FileInputStream(new File(fileName));
      OutputStream out = response.getOutputStream();
      byte[] b = new byte[1024];
      while ((in.read(b))!=-1) {
         out.write(b);
      }
      out.flush();
      in.close();
      out.close();
   }

}
